// Code file original author: Martin Lapierre, http://devinstinct.com

using System;
using System.Text;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using EntLibContrib.Validation.Validators;
using Microsoft.Practices.EnterpriseLibrary.Validation;

namespace EntLibContrib.Validation.Tests.Validators
{
    /// <summary>
    /// Tests <see cref="TypeValidatorAttribute"/>.
    /// </summary>
    [TestClass]
    public class TypeValidatorAttributeFixture
    {
        [TestMethod]
        public void ReturnsSuccessForValidType()
        {
            ObjectValidator<TestTargetC> validator = new ObjectValidator<TestTargetC>("ValidType");
            ValidationResults results = validator.Validate(new TestTargetC());

            Assert.IsTrue(results.IsValid);
        }

        [TestMethod]
        public void ReturnsFailureForInvalidType()
        {
            ObjectValidator<TestTargetC> validator = new ObjectValidator<TestTargetC>("InvalidType");
            ValidationResults results = validator.Validate(new TestTargetC());

            Assert.IsFalse(results.IsValid);
        }

        [TestMethod]
        public void ReturnsFailureForInvalidInheritedType()
        {
            ObjectValidator<TestTargetC> validator = new ObjectValidator<TestTargetC>("InvalidInheritedType");
            ValidationResults results = validator.Validate(new TestTargetC());

            Assert.IsFalse(results.IsValid);
        }

        [TestMethod]
        public void ReturnsSuccessForValidDerivedType()
        {
            ObjectValidator<TestTargetC> validator = new ObjectValidator<TestTargetC>("ValidDerivedType");
            ValidationResults results = validator.Validate(new TestTargetC());

            Assert.IsTrue(results.IsValid);
        }

        [TestMethod]
        public void NegatedReturnsFailureForValidDerivedType()
        {
            ObjectValidator<TestTargetC> validator = new ObjectValidator<TestTargetC>("NegatedValidDerivedType");
            ValidationResults results = validator.Validate(new TestTargetC());

            Assert.IsFalse(results.IsValid);
        }

        /// <summary>
        /// Test target A for this fixture.
        /// </summary>
        private class TestTargetA
        {
        }

        /// <summary>
        /// Test target B for this fixture.
        /// </summary>
        private class TestTargetB
            : TestTargetA
        {
        }

        /// <summary>
        /// Test target C for this fixture.
        /// </summary>
        private class TestTargetC
        {
            [TypeValidator(typeof(TestTargetA), Ruleset = "ValidType")]
            [TypeValidator(typeof(string), Ruleset = "InvalidType")]
            [TypeValidator(typeof(TestTargetB), Ruleset = "InvalidInheritedType")]
            public TestTargetA a = new TestTargetA();

            [TypeValidator(typeof(TestTargetA), Ruleset = "ValidDerivedType")]
            [TypeValidator(typeof(TestTargetA), Ruleset = "NegatedValidDerivedType", Negated = true)]
            public TestTargetB b = new TestTargetB();
        }
    }
}
